﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data;

namespace Card.Utility
{
    public class JsonHelper
    {
        /// <summary>
        /// 转化实体为json
        /// 只转换有JsonAttribute的属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ObjectToJson<T>(T obj)
        {
            StringBuilder strJson = new StringBuilder("{");
            ;
            Type type = typeof(T);
            PropertyInfo[] arrPropertyInfo = type.GetProperties();

            foreach (PropertyInfo prop in arrPropertyInfo)
            {
                if (prop.IsDefined(typeof(JsonAttribute), false))
                {
                    if (prop.IsDefined(typeof(JsonEncryptAttribute), false))
                    {
                        strJson.Append(string.Format("'{0}':'{1}',", prop.Name, Security.Utility.EncryptString(PropertyValueToString(prop, obj))));
                    }
                    else
                    {
                        strJson.Append(string.Format("'{0}':'{1}',", prop.Name, PropertyValueToString(prop, obj)));
                    }
                }
            }

            return strJson.ToString().TrimEnd(',') + "}";
        }

        /// <summary>
        /// 转换List为json
        /// 只转换有JsonAttribute的属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="lst"></param>
        /// <returns></returns>
        public static string ObjectListToJson<T>(List<T> lst)
        {
            StringBuilder strJson = new StringBuilder("[");

            foreach (T obj in lst)
            {
                strJson.Append(ObjectToJson<T>(obj) + ",");
            }

            return strJson.ToString().TrimEnd(',') + "]";
        }

        /// <summary>
        /// 转化实体为json
        /// 只转换属性名在lstPropertyName中的属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="lstPropertyName"></param>
        /// <returns></returns>
        public static string ObjectToJson<T>(T obj, List<string> lstPropertyName)
        {
            StringBuilder strJson = new StringBuilder("{");
            Type type = typeof(T);
            PropertyInfo[] arrPropertyInfo = type.GetProperties();

            foreach (PropertyInfo prop in arrPropertyInfo)
            {
                if (lstPropertyName.Contains(prop.Name))
                {
                    strJson.Append(string.Format("'{0}':'{1}',", prop.Name, PropertyValueToString(prop, obj)));
                }
            }
            return strJson.ToString().TrimEnd(',') + "}";
        }

        /// <summary>
        /// 转化实体为json
        /// 只转换属性名在lstPropertyName中的属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="lst"></param>
        /// <param name="lstPropertyName"></param>
        /// <returns></returns>
        public static string ObjectListToJson<T>(List<T> lst, List<string> lstPropertyName)
        {
            StringBuilder strJson = new StringBuilder("[");

            foreach (T obj in lst)
            {
                strJson.Append(ObjectToJson<T>(obj, lstPropertyName) + ",");
            }

            return strJson.ToString().TrimEnd(',') + "]";
        }

        private static string PropertyValueToString(PropertyInfo prop, object obj)
        {
            object value = prop.GetValue(obj, null);
            if (value is DateTime)
            {
                return Utility.DateTimeFormater.DateTimeToString((DateTime)value);
            }
            if (value != null)
            {
                return String2Json(value.ToString());
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 把DataRow[]转化为json字符串
        /// </summary>
        /// <param name="arrDataRow"></param>
        /// <param name="lstColumns"></param>
        /// <returns></returns>
        public static string DataRowsToJson(DataRow[] arrDataRow, List<string> lstColumns)
        {
            return "[" + string.Join(",",
             arrDataRow.Select<DataRow, string>(row =>
             {
                 return DataRowToJson(row, lstColumns);
             }).ToArray()) + "]";
        }

        /// <summary>
        /// 把DataRow转化为json
        /// </summary>
        /// <param name="drData"></param>
        /// <param name="lstColumns"></param>
        /// <returns></returns>
        public static string DataRowToJson(DataRow drData, List<string> lstColumns)
        {
            return "{" + string.Join(",", lstColumns.Select<string, string>(col =>
            {
                return string.Format("'{0}':'{1}'", col, String2Json(drData[col].ToString()));
            }).ToArray()) + "}";
        }


        public static string DataRowsToJson(DataRow[] arrDataRow)
        {
            if (arrDataRow.Length > 0)
            {
                List<string> lstColumnNames = new List<string>();
                foreach (DataColumn col in arrDataRow[0].Table.Columns)
                {
                    lstColumnNames.Add(col.ColumnName);
                }

                return DataRowsToJson(arrDataRow, lstColumnNames);
            }
            return "[]";
        }

        public static string DataRowToJson(DataRow drData)
        {
            List<string> lstColumnNames = new List<string>();
            foreach (DataColumn col in drData.Table.Columns)
            {
                lstColumnNames.Add(col.ColumnName);
            }

            return DataRowToJson(drData, lstColumnNames);
        }

        public static string DataTableToJson(DataTable dtData)
        {
            if (dtData != null && dtData.Rows.Count > 0 && dtData.Columns.Count > 0)
            {
                List<string> lstColumnNames = new List<string>();
                foreach (DataColumn col in dtData.Columns)
                {
                    lstColumnNames.Add(col.ColumnName);
                }

                return DataRowsToJson(dtData.Select("1=1", string.Empty), lstColumnNames);
            }
            return "[]";
        }

        public static string DataTableToJson(DataTable dtData, List<string> lstColumns)
        {
            return DataRowsToJson(dtData.Select(), lstColumns);
        }

        /// <summary>
        /// 把DataRow转化为json
        /// </summary>
        /// <param name="drData"></param>
        /// <param name="dicColumns">
        /// Key：行名称
        /// Value：json中节点名称
        /// </param>
        /// <returns></returns>
        public static string DataRowToJson(DataRow drData, Dictionary<string, string> dicColumns)
        {
            List<string> lstColumns = dicColumns.Keys.ToList<string>();
            return "{" + string.Join(",", lstColumns.Select<string, string>(col =>
            {
                return string.Format("'{0}':'{1}'", dicColumns[col], String2Json(drData[col].ToString()));
            }).ToArray()) + "}";

        }

        /// <summary>
        /// 把DataRow[]转化为json字符串
        /// </summary>
        /// <param name="arrDataRow"></param>
        /// <param name="dicColumns">
        /// Key：行名称
        /// Value：json中节点名称
        /// </param>
        /// <returns></returns>
        public static string DataRowsToJson(DataRow[] arrDataRow, Dictionary<string, string> dicColumns)
        {
            return "[" + string.Join(",",
             arrDataRow.Select<DataRow, string>(row =>
             {
                 return DataRowToJson(row, dicColumns);
             }).ToArray()) + "]";
        }

        /// <summary>
        /// DataTable转化为json
        /// </summary>
        /// <param name="dtData"></param>
        /// <param name="dicColumns">
        /// Key：行名称
        /// Value：json中节点名称
        /// </param>
        /// <returns></returns>
        public static string DataTableToJson(DataTable dtData, Dictionary<string, string> dicColumns)
        {
            return DataRowsToJson(dtData.Select(), dicColumns);
        }

        /// <summary>
        /// 把字符串转化为json字符串，过滤特殊字符
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string String2Json(string str)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < str.Length; i++)
            {

                char c = str[i];
                switch (c)
                {
                    case '\'':
                        sb.Append("\\\'");
                        break;
                    case '\"':
                        sb.Append("\\\"");
                        break;
                    case '\\':
                        sb.Append("\\\\");
                        break;
                    case '/':
                        sb.Append("\\/");
                        break;
                    case '\b':
                        sb.Append("\\b");
                        break;
                    case '\f':
                        sb.Append("\\f");
                        break;
                    case '\n':
                        sb.Append("\\n");
                        break;
                    case '\r':
                        sb.Append("\\r");
                        break;
                    case '\t':
                        sb.Append("\\t");
                        break;
                    default:
                        sb.Append(c);
                        break;
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 解析客户端用encodeURL编码的字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string DecodeURI(string str)
        {
            return Microsoft.JScript.GlobalObject.decodeURI(str);
        }


        /// <summary>
        /// 解析客户端用escape编码的字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string Unescape(string str)
        {
            return Microsoft.JScript.GlobalObject.unescape(str);
        }

    }

    public class JsonAttribute : System.Attribute
    { }

    public class JsonEncryptAttribute : System.Attribute
    { }
}
